const { EventEmitter } = require('events');

export const deviceListEvent = {
	videoinput: 'videoinput',
	audioinput: 'audioinput',
	audiooutput: 'audiooutput',
	deviceChange: 'deviceChange'
};

export const serviceEvent = {
	error: 'error',
	success: 'success',
	widget: 'widget'
};

type Itarget = {
	type: string;
	event: string;
};

/** 事件枚举类型 */
export enum IEvent {
	LOGIN = 'LOGIN',
	CHECK_IN = 'CHECK_IN',
	CHECK_OUT = 'CHECK_OUT',
	READY = 'READY',
	UNREADY = 'UNREADY',
	ANSWER = 'ANSWER',
	RENDER = 'RENDER',
	REJECT_SESSION = 'REJECT_SESSION',
	HANG_UP = 'HANG_UP',
	BACKGROUND = 'BACKGROUND',
	WATERMARK = 'WATERMARK',
	OTHER_WORK = 'OTHER_WORK',
	CALL_PROGRESS = 'CALL_PROGRESS',
	SYSTEM_ERROR = 'SYSTEM_ERROR',
	ON_DROP = 'ON_DROP',
	STREAM_ADD = 'STREAM_ADD',
	STREAM_END = 'STREAM_END',
	AMS = 'AMS',
	CCS_ERROR = 'CCS_ERROR',
	CCS_DROP = 'CCS_DROP',
	UPDATE_CLIENT_INFO = 'UPDATE_CLIENT_INFO',

	ON_RING = 'ON_RING',
	CANCEL_RING = 'CANCEL_RING',
	OTHER_RECONNECTING = 'OTHER_RECONNECTING',
	OTHER_RESUME_RECONNECT = 'OTHER_RESUME_RECONNECT',
	SESSION_CONNECT_STATUS = 'SESSION_CONNECT_STATUS',

	TEXT_MESSAGE = 'TEXT_MESSAGE',
	RESOURCE_MESSAGE = 'RESOURCE_MESSAGE',
	CUSTOMIZE_MESSAGE = 'CUSTOMIZE_MESSAGE',

	AGENT_JOIN_SESSION = 'AGENT_JOIN_SESSION',
	AGENT_QUIT_SESSION = 'AGENT_QUIT_SESSION',
	CUSTOMER_JOIN_SESSION = 'CUSTOMER_JOIN_SESSION',
	CUSTOMER_QUIT_SESSION = 'CUSTOMER_QUIT_SESSION',
	PUBLISH_MEDIA_STATUS = 'PUBLISH_MEDIA_STATUS',
	RENDER_MEDIA_STATUS = 'RENDER_MEDIA_STATUS',

	INVITATION_PROGRESS = 'INVITATION_PROGRESS',
	VARIABLE_CHANGE = 'VARIABLE_CHANGE',
	ON_RESET_STATUS = 'ON_RESET_STATUS',

	SET_AGENT_STATUS = 'SET_AGENT_STATUS',

	PAGE_LEAVE = 'PAGE_LEAVE',
	LOGOUT = 'LOGOUT',
	PICTURE_IN_PICTURE = 'PICTURE_IN_PICTURE',

	SYNC_MESSAGE = 'SYNC_MESSAGE',

	REAL_TIME_QUALITY = 'REAL_TIME_QUALITY',
	DOM_EVENT = 'DOM_EVENT',
	OBSERVER_JOIN_SESSION = 'OBSERVER_JOIN_SESSION',

	ON_UPGRADE = 'ON_UPGRADE',
	ACCEPT_UPGRADE = 'ACCEPT_UPGRADE',
	REQUEST_UPGRADE = 'REQUEST_UPGRADE',
	REJECT_UPGRADE = 'REJECT_UPGRADE',
	CANCEL_UPGRADE = 'CANCEL_UPGRADE',
	START_VIDEO = 'START_VIDEO',
	AFTER_WORK_END = 'AFTER_WORK_END',
	AFTER_WORK_START = 'AFTER_WORK_START',
	GET_SESSION_MEMBERS = 'GET_SESSION_MEMBERS',
	ON_CCS_RESUME_SUCCESS = 'ON_CCS_RESUME_SUCCESS',
	RECORDING_ALERT = 'RECORDING_ALERT',
	ON_SESSION_RECORD_CRASH = 'ON_SESSION_RECORD_CRASH',
	ON_SYSTEM_RECORD_UPDATE = 'ON_SYSTEM_RECORD_UPDATE',

	REOPEN_FLOAT_WINDOW = 'REOPEN_FLOAT_WINDOW',

	CUSTOMER_VIEW_MARK = 'CUSTOMER_VIEW_MARK', // 访客实时标注相关事件

	ON_SYNC_SESSION_SUMMARY = 'ON_SYNC_SESSION_SUMMARY',
	ON_NEED_DO_SUMMARY_CHANGE = 'ON_NEED_DO_SUMMARY_CHANGE',
	MODIFY_PASSWORD = 'MODIFY_PASSWORD',
	NEED_UPDATE_PASSWORD = 'NEED_UPDATE_PASSWORD',
}

class EventEmit extends EventEmitter {
	static getInstance(): EventEmit {
		// 判断系统是否已经有这个单例
		if (EventEmit.instance === null) {
			EventEmit.instance = new EventEmit();
		}
		return EventEmit.instance; // 单例模式
	}
	private linsteners: string[];

	constructor() {
		super({ captureRejections: true });
		this.linsteners = [];
	}

	setDeviceEventLinstener(target: Itarget, device: MediaDeviceInfo | MediaDeviceInfo[]) {
		this.emit(deviceListEvent[target.event], { ...target, device });
	}

	setServiceEventListener(eventName: IEvent, info: any) {
		this.emit(IEvent[eventName], { data: info, event: eventName });
	}

	setInviteEventListener(target: Itarget, info: any) {
		this.emit('invite', { ...target, ...info });
	}

	addInviteEventListener(ack: any) {
		this.on('invite', ack);
	}

	removeInviteEvent() {
		this.removeAllListeners('invite');
	}

	/**
	 * 设备更新事件监听
	 * @param {function} ack 收到回调消息
	 */
	addDeviceEventLinstener(ack: any) {
		this.on(deviceListEvent['audioinput'], ack);
		this.on(deviceListEvent['videoinput'], ack);
		this.on(deviceListEvent['audiooutput'], ack);
		this.on(deviceListEvent['deviceChange'], ack);
	}

	/**
	 * 移除设备更新事件监听
	 * @param {function} ack 收到回调消息
	 */
	removeDeviceEventLinstener() {
		this.removeAllListeners(deviceListEvent['audioinput']);
		this.removeAllListeners(deviceListEvent['videoinput']);
		this.removeAllListeners(deviceListEvent['audiooutput']);
		this.removeAllListeners(deviceListEvent['deviceChange']);
	}

	addServiceEvent(ack: any) {
		for (let key in IEvent) {
			this.on(IEvent[key], ack);
			this.linsteners = [...this.linsteners, key];
		}
	}

	removeServiceEvent() {
		for (let key in IEvent) {
			this.removeAllListeners(IEvent[key]);
		}
	}
}

export default new EventEmit();
